//
//  VideoPlaybackController.swift
//  MyVideo
//
//  Created by han on 2021/4/20.
//

import UIKit
import AVFoundation

/// 控制多个AVPlayerViewController， VideoPlayerViewControllerCoordinator
class VideoPlaybackController {
    var videos = Video.makeVideos()
    
    weak var videoItemDelegate: VideoPlayerViewControllerCoordinatorDelegate?
    
    private var playbackItems = [Video: VideoPlayerViewControllerCoordinator]()
    
    func prepareForPlayback() {
        do {
            try AVAudioSession.sharedInstance().setCategory(.playback)
        } catch {
            print(error)
        }
    }
    
    private func coordinatorOrNil(for indexPath: IndexPath) -> VideoPlayerViewControllerCoordinator? {
        let video = videos[indexPath.row]
        return playbackItems[video]
    }
    
    func coordinator(for indexPath: IndexPath) -> VideoPlayerViewControllerCoordinator {
        let video = videos[indexPath.row]
        if let playbackItem = playbackItems[video] {
            return playbackItem
        } else {
            let playbackItem = VideoPlayerViewControllerCoordinator(video: video)
            playbackItem.delegate = videoItemDelegate
            playbackItems[video] = playbackItem
            return playbackItem
        }
    }
    
    func indexPath(for coordinator: VideoPlayerViewControllerCoordinator) -> IndexPath? {
        if let index = videos.firstIndex(of: coordinator.video) {
            return IndexPath(item: index, section: 0)
        }
        return nil
    }
    
    func embed(contentForIndexPath indexPath: IndexPath, in parentViewController: UIViewController, containerView: UIView) {
        coordinator(for: indexPath).embedInline(in: parentViewController, container: containerView)
    }
    
    func embed(debugHudForIndexPath indexPath: IndexPath, in cell: VideoBrowserCell) {
        cell.debugHud = coordinator(for: indexPath).externalDebugHud
        cell.debugHud?.status = coordinator(for: indexPath).status
    }
    
    func remove(contentForIndexPath indexPath: IndexPath) {
        coordinatorOrNil(for: indexPath)?.removeFromParentIfNeeded()
    }
    
    func present(contentForIndexPath indexPath: IndexPath, from presentingViewController: UIViewController) {
        coordinator(for: indexPath).presentFullScreen(from: presentingViewController)
    }
    
    func removeAllEmbeddedViewControllers() {
        playbackItems.forEach {
            $0.value.removeFromParentIfNeeded()
        }
    }
    
    func dismissActivePlayerViewController(animated: Bool, completion: @escaping () -> Void) {
        let fullScreenItems = playbackItems
            .filter { $0.value.status.contains(.fullScreenActive) }
            .map { $0.value }
        assert(fullScreenItems.count <= 1, "Never should be more than one thing full screen!")
        if let fullScreenItem = fullScreenItems.first {
            fullScreenItem.dismiss(completion: completion)
        } else {
            completion()
        }
    }
    
}
